<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ajax封装之进阶：参数优化</title>
</head>
<body>
    <script>
        /* 
            用options代替所有参数，并通过对象合并方法 Object.assign(obj1,obj2,...)设置默认值
        */

        // url封装
        function formate(url,dataObj){
            var start = true;
            var type = "GET";
            /* 
                * 根据数据类型判断请求类型
                * 也可以根据实参集合长度arguments.length判断：1为post，2为get
             */
            if(typeof url === 'object' && !(url instanceof Array)){
                dataObj = url;
                url = '';
                type = "POST";
            }

            // 2.参数拼接
            for(var key in dataObj){
                // get请求
                if(type === "GET"){
                    url += (start?"?":"&")+key+"="+dataObj[key];
                // post请求
                }else{
                    url += (start?"":"&")+key+"="+dataObj[key];
                }
                start = false;
            }
            // 注意jsonp请求需要把函数名也写进去，不然没参与到拼接返回不了数据
            // console.log(url);
            return url;
        }

        // jsonp的ajax封装
        function ajax(options){
            // 参数优化：数据对象拼接
            options = Object.assign({
                // 默认get请求、路径为空、数据为空、函数名为callback、回调为空
                method:'GET',
                _callback:function(){},
                url:'',
                dataObj:{},
                jsonpcallback:'callback',
            },options)
            console.log(options);

            // 1.请求方式为jsonp时
            if(options.method === "jsonp"){
                // dataObj为空时，设置默认值
                /* dataObj = dataObj || {}; */
                
                /* dataObj.jsonpcallback = dataObj.jsonpcallback ? dataObj.jsonpcallback : "callback"; */

                var script = document.createElement("script");
                script.src = formate(options.url,options.dataObj);
                document.body.appendChild(script);

                window[options.jsonpcallback] = function(data){
                    options._callback(data);
                }
                script.remove();
            }
            // 2.请求方式为get/post时
            else{
                var xhr = new XMLHttpRequest();

                xhr.open(options.method,options.method.toUpperCase() ==="GET" ? formate(options.url,options.dataObj) : options.url);

                if(options.method.toUpperCase()==="POST"){
                    xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
                }

                xhr.send(options.method.toUpperCase() ==="POST" ? formate(options.dataObj) : '');

                xhr.onreadystatechange = function(){
                    if(xhr.readyState===4&&/^2\d{2}$/.test(xhr.status)){
                        options._callback(xhr.responseText);
                    }
                }
            }
        }


        /* ajax({
            method:"GET",
            url:"04_ajax_first.php",
            _callback:function(data){
                console.log(data);
            }
        }) */

        // ajax({
        //     method:"jsonp",
        //     url:"https://api.gogoup.com/p1/data/recommend",
        //     dataObj:{
        //         type:0,     
        //         pageNo:2, 
        //         pageSize:5, 
        //         fromId:379, 
        //         jsonpcallback:'callback',
        //         _:Date.now()
        //     },
        //     _callback:function(data){
        //         console.log(data);
        //     }
        // })

        ajax({ 
            method : "jsonp" , 
            url : "https://www.baidu.com/sugrec",
            dataObj : {
                    pre:1,
                    p:3,
                    ie:"utf-8",
                    json:1,
                    prod:"pc",
                    from:"pc_web",
                    sugsid:"32218,1425,31672,32139,31254,32045,32230,32299,31639",
                    wd:"hello world",
                    req:2,
                    csor:5,
                    cb:"callback",
                    _:Date.now()
            },
            jsonpcallback : "callback",
            _callback : function(data){
                console.log(data);
            }
        })
    </script>
</body>
</html>